package heap

/*
类对象引用：
 System.out.println(String.class); && System.out.println("a".getClass());
*/

type Object struct {
	// 存放对象指针
	class *Class
	//// 存放实例对象
	//fields Slots
	// 既可以表示实例对象,也可以表示数组
	data interface{}
	// 用于反射实现
	extra interface{}
	// 引用计数器
	count int
}

// newObject 创建一个新的对象实例
func newObject(class *Class) *Object {
	obj := &Object{}
	obj.class = class
	obj.data = newSlots(class.instanceSlotCount)
	obj.count = 1
	return obj
}

func (self *Object) IsInstanceOf(class *Class) bool {
	return class.isAssignableFrom(self.class)
}

// AddRef 增加对象的引用计数
func (self *Object) AddRef() {
	self.count++
	//fmt.Printf("Object name: %v,\tcount: %v\n", self.class.name, self.count)
}

// Release 减少对象的引用计数，并在计数为0时释放对象
func (self *Object) Release() {
	self.count--
	if self.count == 0 {
		self.Free()
	}
}

// Free 释放对象占用的资源
func (self *Object) Free() {
	if slots, ok := self.data.(Slots); ok {
		for _, slot := range slots {
			if slot.ref != nil {
				slot.ref.Release()
			}
		}
	}
	// Clear other references to allow GC to reclaim memory
	self.class = nil
	self.data = nil
	self.extra = nil
}

// getters
func (self *Object) Class() *Class {
	return self.class
}

// 获取字段表
func (self *Object) Fields() Slots {
	return self.data.(Slots)
}
func (self *Object) GetRefVar(name, descriptor string) *Object {
	field := self.class.getField(name, descriptor, false)
	slots := self.data.(Slots)
	return slots.GetRef(field.slotId)
}
func (self *Object) Data() interface{} {
	return self.data
}
func (self *Object) Extra() interface{} {
	return self.extra
}

// setters
func (self *Object) SetExtra(extra interface{}) {
	self.extra = extra
}

// 设置引用类型变量
func (self *Object) SetRefVar(name, descriptor string, ref *Object) {
	field := self.class.getField(name, descriptor, false)
	slots := self.data.(Slots)
	slots.SetRef(field.slotId, ref)
}
